<?php

namespace app\utils;

use app\msgapi\model\System;
use think\Image;

class Filesystem
{

    /**
     * 使用tp的image类，对本地图片进行压缩、调整尺寸
     * @param string $url 图片路径
     * @param int $w 推荐宽
     * @param int $h 推荐高
     * @return array
     */
    public static function resizeImage(string $url, $w = 0, $h = 0): array
    {
        // intervention/image处理gif图后不会动了，这里使用tp的image的修改版，不要升级
        // 判断上传文件是图片
        if (function_exists("exif_imagetype")) {  // exif_imagetype函数快得多,需exif扩展支持，虚拟主机无法修改配置文件
            $is_ok = exif_imagetype('.' . $url);
        } else {
            $is_ok = getimagesize('.' . $url);  // 使用getimagesize代替
        }
        // 文件是图片时压缩、缩小等处理
        if ($is_ok !== false) {
            $config = System::getSys('upload_config');
            if ($config['img_resize'] == 'on') {    // 开启图片压缩后，上传后调整图片大小
                if (!extension_loaded('gd')) {
                    return ['code' => 0, 'msg' => '请开启gd扩展'];
                }
                $img = Image::open('.' . $url);
                $_w = $img->width();
                $_h = $img->height();   // 图片的实际宽高
                // 如果开启等比缩小，并且宽高有任一大于推荐才进行等比缩小
                if ($config['img_resize_opt'] == 2 && (($w && $_w > $w) || ($h && $_h > $h))) {
                    $save_w = $w ?: $_w;
                    $save_h = $h ?: $_h;   // 需要缩小就按照推荐尺寸进行保存
                } else {  // 没有开启缩小的，仅压缩
                    $save_w = $_w;
                    $save_h = $_h; // 不需要的，按照实际尺寸
                }
                /** scale参数自己新增参数，其他项目引用时注意。scale参数仅用于等比缩小图片时，留空为原image类的裁剪方法
                 * png透明正常，gif透明图会自动加上白色背景，后续再寻找解决方案。
                 */
                $img->thumb($save_w, $save_h, 1, 'scale')->save('.' . $url);    // 等比生成图片方法，覆盖原文件。默认80品质
            }
        }

        return ['code' => 0, 'url' => $url];
    }

    /**
     * 递归获取目录下指定后缀的文件列表
     * @param string $path
     * @param string $allowFiles 后缀名'gif|jpg|jpeg|png'
     * @param array $files
     * @return array
     */
    public static function getFiles(string $path, string $allowFiles, array &$files = []): array
    {
        if (!is_dir($path)) {
            return [];
        }
        if (substr($path, strlen($path) - 1) != '/') {
            $path .= '/';
        }
        $handle = opendir($path);
        while (false !== ($file = readdir($handle))) {
            if ($file == '.' || $file == '..') {
                continue;
            }
            $path2 = $path . $file;
            if (is_dir($path2)) {
                static::getFiles($path2, $allowFiles, $files);
            } else {
                if (preg_match("/\.(" . $allowFiles . ")$/i", $file)) {
                    $files[] = [
                        'url' => substr($path2, 1),
                        'mtime' => filemtime($path2)
                    ];
                }
            }
        }
        return $files;
    }
}